package com.itcast.tanhua.dubbo.server.api;
import com.alibaba.dubbo.config.annotation.Service;
import com.itcast.tanhua.dubbo.server.service.IdService;
import com.itcast.tanhua.dubbo.server.domain.*;
import com.itcast.tanhua.dubbo.server.vo.PageInfo;
import com.mongodb.client.result.DeleteResult;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;

import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;


/**
 * @PachageName: com.itcast.tanhua.dubbo.server.api
 * @ClassName:
 * @Description: TODO
 * @Author: Hushi
 * @DateTime: 2021/2/1711:26
 * @Version 1.0
 */
@Service(version = "1.0.0")
@Component
@Slf4j
public class QuanZiApiImpl implements QuanZiApi {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdService idService;
    @Override
    public boolean savePublish(Publish publish) {
        //校验UserId
        if (publish.getUserId() == null) {
            return false;
        }

        try {
            //填充信息
            publish.setId(ObjectId.get());
            publish.setSeeType(1); //谁可以看，1-公开，2-私密，3-部分可见，4-不给谁看
            publish.setCreated(System.currentTimeMillis());

            publish.setPid(idService.createId("PUBLISH",publish.getId().toHexString()));
            //将数据保存到发布表中
            this.mongoTemplate.save(publish);

            //将数据添加到相册表中(保存本用户发布的所有动态)
            Album album = new Album();
            album.setId(ObjectId.get());
            album.setCreated(System.currentTimeMillis());
            album.setPublishId(publish.getId());
            //写入数据库
            this.mongoTemplate.save(album, "quanzi_album_" + publish.getUserId());

            //将动态写进其他好友的时间线表中
            Query query = Query.query(Criteria.where("userId").is(publish.getUserId()));
            List<Users> users = this.mongoTemplate.find(query, Users.class);
            for (Users user : users) {
                TimeLine timeLine = new TimeLine();
                timeLine.setDate(System.currentTimeMillis());
                timeLine.setId(ObjectId.get());
                timeLine.setUserId(publish.getUserId());
                timeLine.setPublishId(publish.getId());
                this.mongoTemplate.save(timeLine,"quanzi_time_line_" + user.getFriendId());
            }
        } catch (Exception e) {
            log.error("圈子发布动态保存错误!",e);
            return false;
        }
        return true;
    }

    @Override
    public PageInfo<Publish> queryPublishList(Long userId, Integer page, Integer pageSize){
        String tableName = "quanzi_time_line_";
        if (userId == null){
            tableName = tableName + "recommend";
        }
        else{
            tableName = tableName + userId;
        }
        //根据时间倒序查询时间线表
        Pageable pageRequest = PageRequest.of(page - 1,pageSize, Sort.by(Sort.Order.desc("date")));
        Query queryUsers = new Query().with(pageRequest);
        List<TimeLine> timeLines = this.mongoTemplate.find(queryUsers, TimeLine.class, tableName);
        //收集好友动态的PublishId(发布ID)
        List<ObjectId> list = new ArrayList<>();
        for (TimeLine timeLine : timeLines) {
            list.add(timeLine.getPublishId());
        }

        //根据时间倒序查询好友动态,放到pageInfo中
        Query queryPublish = Query.query(Criteria.where("id").in(list)).with(Sort.by(Sort.Order.desc("created")));
        List<Publish> publishList = this.mongoTemplate.find(queryPublish, Publish.class);
        PageInfo<Publish> pageInfo = new PageInfo<>();
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        pageInfo.setRecords(publishList);
        pageInfo.setTotal(0);
        return pageInfo;
    }

    /**
     * 点赞
     * @param userId
     * @param publishId
     * @return
     */
    @Override
    public boolean saveLikeComment(Long userId, String publishId) {
        Query query = Query.query(Criteria.where("userId").is(userId).and("publishId").is(new ObjectId(publishId)).and("commentType").is(1));
        long count = this.mongoTemplate.count(query, Comment.class);
        if (count > 0){
            return false;
        }
        return this.saveComment(userId,publishId,1,null);
    }

    /**
     *  取消点赞、喜欢等
     * @param userId
     * @param publishId
     * @param commentType
     * @return
     */
    @Override
    public boolean removeComment(Long userId, String publishId, Integer commentType) {

        Query query = Query.query(Criteria.where("userId").is(userId).and("publishId").is(new ObjectId(publishId)).and("commentType").is(commentType));
        DeleteResult remove = this.mongoTemplate.remove(query, Comment.class);
        return remove.getDeletedCount() > 0;
    }

    /**
     * 喜欢
     * @param userId
     * @param publishId
     * @return
     */
    @Override
    public boolean saveLoveComment(Long userId, String publishId) {
        Query query = Query.query(Criteria.where("userId").is(userId).and("publishId").is(new ObjectId(publishId)).and("commentType").is(3));
        long count = this.mongoTemplate.count(query, Comment.class);
        if (count > 0){
            return false;
        }
        return this.saveComment(userId,publishId,3,null);
    }

    /**
     * 保存评论
     * @param userId
     * @param publishId
     * @param type
     * @param content
     * @return
     */
    @Override
    public boolean saveComment(Long userId, String publishId, Integer type, String content) {

        try {
            Comment comment = new Comment();
            comment.setContent(content);
            comment.setCommentType(type);
            comment.setIsParent(true);
            comment.setPublishId(new ObjectId(publishId));
            comment.setId(ObjectId.get());
            comment.setUserId(userId);
            comment.setCreated(System.currentTimeMillis());
            //设置发布人的Id
            Publish byId = this.mongoTemplate.findById(comment.getPublishId(), Publish.class);
            if (byId != null){
                comment.setPublishUserId(byId.getUserId());
            }else{
                Video video = this.mongoTemplate.findById(comment.getPublishId(), Video.class);
                if (video != null) {
                    comment.setPublishUserId(video.getUserId());
                }
            }

            this.mongoTemplate.save(comment);
            return true;
        } catch (Exception e) {
            log.error("保存评论失败~ userId : " + userId,e);
        }
        return false;
    }

    @Override
    public Long queryCommentCount(String publishId, Integer type) {
        Query query = Query.query(Criteria.where("publishId").is(new ObjectId(publishId)).and("commentType").is(type));
        return this.mongoTemplate.count(query,Comment.class);
    }

    @Override
    public Publish queryPublishById(String id) {

        try {
            if ("visitors".equals(id)){
                return null;
            }
            return this.mongoTemplate.findById(new ObjectId(id), Publish.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public PageInfo<Comment> queryCommentList(String publishId, Integer page, Integer pageSize) {

        Pageable pageRequest = PageRequest.of(page - 1,pageSize,Sort.by(Sort.Order.asc("created")));
        Query query = Query.query(Criteria.where("publishId").is(new ObjectId(publishId)).and("commentType").is(2)).with(pageRequest);

        //评论分页查询
        List<Comment> comments = this.mongoTemplate.find(query, Comment.class);

        PageInfo<Comment> pageInfo = new PageInfo<>();
        pageInfo.setTotal(0);
        pageInfo.setPageSize(pageSize);
        pageInfo.setPageNum(page);
        pageInfo.setRecords(comments);
        return pageInfo;
    }

    @Override
    public PageInfo<Comment> queryCommentListByUser(Long userId, Integer type, Integer page, Integer pageSize) {

        Pageable pageRequest = PageRequest.of(page - 1,pageSize,Sort.by(Sort.Order.desc("created")));
        Query query = Query.query(Criteria.where("publishUserId").is(userId).and("commentType").is(type)).with(pageRequest);
        List<Comment> comments = this.mongoTemplate.find(query, Comment.class);
        PageInfo<Comment> pageInfo = new PageInfo<>();
        pageInfo.setTotal(0);
        pageInfo.setPageNum(page);
        pageInfo.setPageSize(pageSize);
        pageInfo.setRecords(comments);
        return pageInfo;
    }

    @Override
    public List<Publish> queryPublishByPids(List<Long> pidList) {

        Query query = Query.query(Criteria.where("pid").in(pidList));
        return this.mongoTemplate.find(query,Publish.class);
    }

    @Override
    public PageInfo<Publish> queryAlbumList(Long userId, Integer page, Integer pageSize) {
        PageInfo<Publish> pageInfo = new PageInfo<>();
        pageInfo.setTotal(0);
        pageInfo.setPageSize(pageSize);
        pageInfo.setPageNum(page);

        Pageable pageRequest = PageRequest.of(page - 1,pageSize,Sort.by(Sort.Order.desc("created")));
        Query query = new Query().with(pageRequest);
        List<Album> albumList = this.mongoTemplate.find(query, Album.class, "quanzi_album_" + userId);

        if (CollectionUtils.isEmpty(albumList)){
            return pageInfo;
        }

        List<ObjectId> objectIds = new ArrayList<>();
        for (Album album : albumList) {
            if (!objectIds.contains(album.getPublishId())){
                objectIds.add(album.getPublishId());
            }
        }

        Query queryPublish = Query.query(Criteria.where("id").in(objectIds)).with(Sort.by(Sort.Order.desc("created")));
        List<Publish> publishList = this.mongoTemplate.find(queryPublish, Publish.class);
        pageInfo.setRecords(publishList);
        return pageInfo;
    }
}
